﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Coldairarrow.DotNettySocket;
using DataAnalysisGPRS;
using DataBase;
using Infrastructure;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using SysLog;

namespace DataCluster.Console
{
    public class TcpAndUdpSocketService : IHostedService
    {
        private readonly IOptions<AppConfig> _appConfig;

        public TcpAndUdpSocketService(IOptions<AppConfig> appConfig)
        {
            _appConfig = appConfig;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            LogHelper.Info("Starting");

            #region 开启TCP
            var tcpServer = await SocketBuilderFactory.GetTcpSocketServerBuilder(_appConfig.Value.SocketServer.Port, _appConfig.Value.SocketServer.ReaderIdleTimeSeconds)
                    //.SetLengthFieldEncoder(2)
                    //.SetLengthFieldDecoder(ushort.MaxValue, 0, 2, 0, 2)
                    .OnConnectionClose((server, connection) =>
                    {

                        LogHelper.Debug($"TCP连接关闭,连接名[{connection.ClientAddress.Address.MapToIPv4()}:{connection.ClientAddress.Port}],当前连接数:{server.GetConnectionCount()}");
                    })
                    .OnException(ex =>
                    {
                        LogHelper.Warn($"TCP服务端异常:{ex.Message}");
                    })
                    .OnNewConnection((server, connection) =>
                    {
                        connection.ConnectionName = $"名字{connection.ConnectionId}";
                        LogHelper.Debug($"TCP新的连接[{connection.ClientAddress.Address.MapToIPv4().ToString()}]:{connection.ConnectionName},当前连接数:{server.GetConnectionCount()}");
                    })
                    .OnRecieve((server, connection, bytes) =>
                    {
                        //LogHelper.Debug($"服务端:数据{Encoding.UTF8.GetString(bytes)}");

                        DotNettyTcpSession mSession = new DotNettyTcpSession(connection);
                        new AnalysisGPRS().Analysis(bytes, mSession);

                        //connection.Send(new byte[] { 01 });
                    })
                    .OnSend((server, connection, bytes) =>
                    {
                        //LogHelper.Debug($"向连接名[{connection.ConnectionName}]发送数据:{Encoding.UTF8.GetString(bytes)}");
                    })
                    .OnServerStarted(server =>
                    {
                        LogHelper.Info($"TCP服务启动");
                    }).BuildAsync();
            #endregion

            #region 开启 UDP
            var updServer = await SocketBuilderFactory.GetUdpSocketBuilder(_appConfig.Value.SocketServer.Port)
                    .OnClose(server =>
                    {
                        LogHelper.Info($"UDP服务端关闭");
                    })
                    .OnException(ex =>
                    {
                        LogHelper.Warn($"UDP服务端异常:{ex.Message}");
                    })
                    .OnRecieve((server, point, bytes) =>
                    {
                        //LogHelper.Debug($"服务端:收到来自[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");

                        DotNettyUdpSession mSession = new DotNettyUdpSession(server, point);
                        new AnalysisGPRS().Analysis(bytes, mSession);

                        //server.Send(new byte[] { 01 }, point);
                    })
                    .OnSend((server, point, bytes) =>
                    {
                        //LogHelper.Debug($"服务端发送数据:目标[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
                    })
                    .OnStarted(server =>
                    {
                        LogHelper.Info($"UDP服务端启动");
                    }).BuildAsync();
            #endregion

            // 开启入库
            DBQueueManager.Start();
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            LogHelper.Info("Stopping.");
            DBQueueManager.Stop();
            return Task.CompletedTask;
        }
    }
}
